package com.gupaoedu.vip.spring.formework.aop;

import java.lang.reflect.Field;
import java.lang.reflect.Proxy;

/**
 * Created by Tom on 2018/5/2.
 */
public class GPAopProxyUtils {


    public static  Object getTargetObject(Object proxy) throws Exception{
        //先判断一下，这个传进来的这个对象是不是一个代理过的对象
        //如果不是一个代理对象，就直接返回
        if(!isAopProxy(proxy)){
            return proxy;
        }
        return getProxyTargetObject(proxy);
    }

    private static boolean isAopProxy(Object object){
        return Proxy.isProxyClass(object.getClass());
    }


    private static Object getProxyTargetObject(Object proxy) throws Exception{
        /**
         * 默认生成的 $proxy0 proxy1 proxy2 ...  都是 Proxy 类型的
         *  这里的 Object proxy 其实是一个 GPAopProxy 的动态代理
         *  Proxy.newProxyInstance(clazz.getClassLoader(),clazz.getInterfaces(),this);
         *
         *  //this  点进去看就是 h
         *
         *      public static Object newProxyInstance(ClassLoader loader,
         *                                           Class<?>[] interfaces,
         *                                           InvocationHandler h)
         *
         *  //Proxy 类型的 成员变量 InvocationHandler h   上文传的是this 也就是 GPAopProxy
         *
         *  public class Proxy implements java.io.Serializable {
         *       /**
         *      * the invocation handler for this proxy instance.
         *      * @serial
         *      *
         *      protected InvocationHandler h;
         *        ...
         */
        Field h = proxy.getClass().getSuperclass().getDeclaredField("h");
        h.setAccessible(true);
        GPAopProxy aopProxy = (GPAopProxy) h.get(proxy);
        /**
         * private Object target;
         * GPAopProxy 成员变量  target
         */
        Field target = aopProxy.getClass().getDeclaredField("target");
        target.setAccessible(true);
        return  target.get(aopProxy);
    }

}
